Automation Test with Selenium Cucumber, TestNG and Gradle
Trust you have heard about Cucumber, Jasmine, mocha… Hey, this is an automation test blog, you want to change the topic to discuss healthy food? Not really! These are also the name of some of the famous automation test framework 🙂 Today I’d like to introduce an automation test framework based on JAVA, Cucumber, Selenium, TestNG and Gradle. Jasmine and Mocha are JavaScript relevant, I will discuss them in separate session later.
1. What is BDD?
Cucumber is an automation test tool which leverages the power of Behavior Driven Development (BDD). What is BDD? This is a big topic. I normally need 2-3 hours to conduct a BDD training for an organization. Simply speaking, it is an Agile software development process which encourages collaboration among developers, business analysts, and QA. Business requirement is articulated as feature files, which are in plain English and with Gherkin format.
In my approach, test cases are wrote in the format of feature file with clear operation steps and expected criteria. Cucumber can convert the feature file into JAVA code–each step maps to a JAVA method. Following is a sample feature file.
2. Integration with TestNG and Gradle
If you have read my blog Page Object Model and Fluent Design I, and Page Object Model and Fluent Design II, you may have basic idea on conducting automation test using Selenium. Here to step further, we need to integrate a typical web automation framework using Selenium, TestNG and Gradle with Cucumber.
Cucumber JAVA module is implemented in JUnit actually, thus it is easier to use JUnit+Cucumber in your test project. However if your project is always using TestNG, now you want to add Cucumber support, we can still make them work well.
Firstly, add following cucumber dependency into your build.gradle file.
compile group: ‘io.cucumber’, name: ‘cucumber-java’, version: ‘4.8.0’
compile group: ‘io.cucumber’, name: ‘cucumber-testng’, version: ‘4.8.0’
If you are not the first time using Cucumber, keep in mind that Cucumber community package name has been progressed from info.cukes, then cucumber.api.java, now it is io.cucumber. Make sure you add the right dependency and import the right package into your code.
In cucumber-testng library, there is an important class AbstractTestNGCucumberTests , each of your test class should extends from this class. However if you are building a framework, you should always have some initialization and teardown work apply to all tests. And to follow the DRY principle, we need to abstract these work to allow each test has these initialization and teardown easily. Thus I suggest to design another abstract class to extends from AbstractTestNGCucumberTests, and use TestNG annotation like @BeforeClass, @BeforeSuite, @AfterSuite to conduct relevant initialization and teardown. Then each of your Cucumber Test class extends from AbstractCucumberWebTest.
3. CucumberOptions
It is mandatory to add @CucumberOptions before your cucumber test class definition. Major properties are as following:
- feature: the feature file location. We can map more than one feature files to a cucumber test class actually but I don’t suggest to do that
- plugin: the test result. Normally should be presented in both json and html format. This is extremely important for continuous integration and test failure investigation
- glue: the step definition file which is converted by Cucumber from the feature file. Cucumber will search the whole folder defined here to find the step definition methods
- snippets: there are two options here. SnippetType.CAMELCASE and SnippetType.UNDERSCORE. This defines the JAVA code naming convention generated by Cucumber. I suggest SnippetType.CAMELCASE as this is consistent with our general JAVA naming habit.
BTW, Cucumber only generate skeleton on the step definition JAVA code. We still need to add business logic inside. This is the same for any other automation test thus I skip this session.
4. Gradle task
Finally we need to be able to run the test, not only locally from your own computer, but also from the continuous integration server, like Jenkins.
If you check the source code of AbstractTestNGCucumberTests, you will understand each our cucumber test class is a TestNG class initially. Thus I suggest to have TestNG file maps to each cucumber test class, and in build.gradle file, we we create task for each TestNG file.
Typically, one task maps to one TestNG file; one TestNG file maps to one Cucumber Test; one Cucumber Test maps to one feature file; one feature file maps to a set of business scenario in same category. This approach would reduce lots of maintenance effort.
BDD automation test is getting accepted by more and more professionals. Next session I will introduce BDD style in cypress.